package top.lixunda.ecommerce.server.user.controller;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;
import top.lixunda.commerce.common.core.entity.MessageObject;
import top.lixunda.common.utils.ObjectValidators;
import top.lixunda.common.validate.XumValid;
import top.lixunda.ecommerce.server.business.BaseController;
import top.lixunda.ecommerce.server.business.api.entity.cache.CacheUser;
import top.lixunda.ecommerce.server.business.api.entity.vo.ImageUploadTokenVO;
import top.lixunda.ecommerce.server.business.api.entity.QiNiuCallbackBody;
import top.lixunda.ecommerce.server.good.api.entity.db.QiNiuFileDO;
import top.lixunda.ecommerce.server.good.api.feign.IFeignQiNiuFileController;
import top.lixunda.ecommerce.server.user.api.entity.dto.UserInfoChgDTO;
import top.lixunda.ecommerce.server.user.api.entity.db.UserInfoDO;
import top.lixunda.ecommerce.server.user.api.controller.IUserInfoController;
import top.lixunda.ecommerce.server.user.api.entity.vo.UserPublicInfoVO;
import top.lixunda.ecommerce.server.user.service.IUserInfoService;

import java.util.List;
import java.util.UUID;

/**
 * @author Xumda
 * @version time:2019/12/14 17:03
 */
@Slf4j
@RestController
public class UserInfoController extends BaseController implements IUserInfoController {

    private static final String CALLBACK_URL =
            "http://lixunda.top:2100/middle-user/userInfo/createHeadImageUploadToken";

    private final IUserInfoService userInfoService;

    private final IFeignQiNiuFileController feignQiNiuFileController;

    @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
    @Autowired
    public UserInfoController(IUserInfoService userInfoService,
                              IFeignQiNiuFileController feignQiNiuFileController) {
        this.userInfoService = userInfoService;
        this.feignQiNiuFileController = feignQiNiuFileController;
    }

    /**
     * 根据用户类型查询人员基本信息，发送消息时使用
     *
     * @param type 用户类型
     * @return 用户信息列表
     */
    @Override
    public MessageObject<List<UserInfoDO>> queryUserByType(String type) {
        List<UserInfoDO> result = userInfoService.queryUserByType(type);
        return getSuccessMessageObject("获取数据成功", result);
    }

    /**
     * 查询当前登陆账户基本信息
     *
     * @return 用户基本信息
     */
    @Override
    @GlobalTransactional
    public MessageObject<UserInfoDO> queryCurrentUserInfo() {
        CacheUser userDetail = currentUserCacheNotNull();
        UserInfoDO userInfo = userInfoService.getById(String.valueOf(userDetail.getAccount()));
        return getSuccessMessageObject("获取用户信息成功", userInfo);
    }

    /**
     * 通过用户编号查询普通用户的公开信息
     *
     * @param id 用户编号
     * @return 用户基本信息
     */
    @Override
    public MessageObject<UserPublicInfoVO> queryUserPublicInfoById(Integer id) {
        if (ObjectValidators.isEmpty(id)) {
            throw getAppException("用户编号不能为空");
        }
        UserInfoDO userInfoDO = userInfoService.getById(id);
        UserPublicInfoVO vo = UserPublicInfoVO.fromUserInfoDO(userInfoDO);
        return getSuccessMessageObject("获取数据成功", vo);
    }

    /**
     * 通过用户编号查询普通用户的公开信息, 批量查询
     *
     * @param ids 用户编号
     * @return 用户基本信息
     */
    @Override
    public MessageObject<List<UserPublicInfoVO>> queryUserPublicInfoByIds(List<Integer> ids) {
        if (ObjectValidators.isEmpty(ids)) {
            throw getAppException("用户编号不能为空");
        }
        List<UserInfoDO> list = (List<UserInfoDO>) userInfoService.listByIds(ids);
        List<UserPublicInfoVO> voList = UserPublicInfoVO.fromUserInfoDO(list);
        return getSuccessMessageObject("获取数据成功", voList);
    }

    /**
     * 更新当前登陆账户基本信息
     *
     * @param userInfoChgDTO UserInfoChgDTO
     * @return 更改后的用户基本信息
     */
    @Override
    @GlobalTransactional
    public MessageObject<UserInfoDO> updateCurrentUserInfo(@XumValid UserInfoChgDTO userInfoChgDTO) {
        // 更新字段全部为空
        if (!userInfoChgDTO.haveUpdateData()) {
            UserInfoDO userInfo = userInfoService.getById(String.valueOf(currentUserCacheNotNull().getAccount()));
            return MessageObject.success("没有更新数据", userInfo);
        }
        UserInfoDO userInfo = userInfoChgDTO.toUserInfo();
        userInfo.setAccountId(currentUserCacheNotNull().getAccount());
        boolean success = userInfoService.updateById(userInfo);
        if (success) {
            return getSuccessMessageObject("更新用户信息成功", userInfo);
        } else {
            throw getAppException("获取用户基本信息失败");
        }
    }

    /**
     * 获取上传头像凭证
     *
     * @return 上传头像凭证
     */
    @Override
    public MessageObject<ImageUploadTokenVO> createHeadImageUploadToken() {
        CacheUser userInfoDO = currentUserCacheNotNull();
        ImageUploadTokenVO imageUploadTokenVO = createUploadToken(
                String.valueOf(userInfoDO.getAccount()), CALLBACK_URL,
                UUID.randomUUID().toString());
        return getSuccessMessageObject("获取上传凭证成功", imageUploadTokenVO);
    }

    /**
     * 获取上传头像凭证
     *
     * @param qiNiuCallbackBody 回调参数
     * @return 上传头像凭证
     */
    @Override
    public MessageObject<QiNiuCallbackBody> headImageUploadCallback(QiNiuCallbackBody qiNiuCallbackBody) {
        if (ObjectValidators.isEmpty(qiNiuCallbackBody)) {
            return getErrorMessageObject("七牛云回调失败，参数为空");
        }
        if (ObjectValidators.isEmpty(qiNiuCallbackBody.getUserId())) {
            return getErrorMessageObject("七牛云回调失败，确实必要的参数userId");
        }
        if (ObjectValidators.isEmpty(qiNiuCallbackBody.getKey())) {
            return getErrorMessageObject("七牛云回调失败，确实必要的参数key");
        }
        log.debug("上传头像回调：{}", qiNiuCallbackBody.toString());
        // 鉴权
        CacheUser userInfoDO = currentUserCacheNotNull();
        if (!String.valueOf(userInfoDO.getAccount()).equals(qiNiuCallbackBody.getUserId())) {
            throw getAppException("七牛云回调失败，权限不足");
        }
        // 保存图片信息
        QiNiuFileDO qiNiuFileDO = new QiNiuFileDO();
        BeanUtils.copyProperties(qiNiuCallbackBody, qiNiuFileDO);
        feignQiNiuFileController.addQiNiuFileInfo(qiNiuFileDO);
        // 根据用户头像信息
        userInfoService.update(new LambdaUpdateWrapper<UserInfoDO>()
                .eq(UserInfoDO::getAccountId, userInfoDO.getAccount())
                .set(UserInfoDO::getHeadImg, qiNiuCallbackBody.getKey()));
        return getSuccessMessageObject("保存头像成功");
    }


}
